﻿using MovingChame.Web.Helpers;
using MovingChame.Web.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MovingChame.Web.Infrastructure
{
    public class ScheduleProvider : IScheduleProvider
    {
        #region Static Variable
        private static ScheduleProvider current;
        public static ScheduleProvider Current
        {
            get
            {
                if (current == null)
                    current = new ScheduleProvider();
                return current;
            }
        }
        #endregion

        #region Configuration
        private string applicationName;
        public string ApplicationName
        {
            get { return applicationName; }
            set { applicationName = value; }
        }

        private string connectionStringName;
        private string providerName;
        private MovingChameModelContainer db;

        public void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            providerName = name;

            if (config["applicationName"] != null)
                applicationName = config["applicationName"];

            if (config["connectionStringName"] != null)
            {
                connectionStringName = config["connectionStringName"];
                db = new MovingChameModelContainer();
                db.Database.Connection.ConnectionString = ConfigurationHelper.GetConnectionString(connectionStringName);
            }
            else
                db = new MovingChameModelContainer();
        }

        private ScheduleProvider()
        {
            Initialize("ScheduleProvider", new System.Collections.Specialized.NameValueCollection());
        }
        #endregion

        #region Interface Methods - Add, update, remove
        public int AddSchedule(int locationId, int tourId, DateTime startTime, DateTime endTime, short dateOrder)
        {
            var schedule = new Schedule
                {
                    LocationId = locationId,
                    TourId = tourId,
                    StartTime = startTime,
                    EndTime = endTime,
                    DateOrder = dateOrder
                };
            db.Schedules.Add(schedule);
            db.SaveChanges();
            return schedule.Id;
        }

        public Boolean UpdateSchedule(int scheduleId, Schedule updatedSchedule)
        {
            Schedule schedule = GetScheduleById(scheduleId);
            if (schedule == null)
                return false;
            db.Entry(schedule).CurrentValues.SetValues(updatedSchedule);
            db.SaveChanges();
            return true;
        }

        public Boolean UpdateSchedules(List<Schedule> updatedSchedules)
        {
            Boolean error = true;
            foreach (Schedule updatedSchedule in updatedSchedules)
            {
                error = UpdateSchedule(updatedSchedule.Id, updatedSchedule);
                if (!error) return false;
            }
            db.SaveChanges();
            return true;
        }

        public Boolean RemoveSchedule(int scheduleId)
        {
            var schedule = db.Schedules.SingleOrDefault(o => o.Id == scheduleId);
            if (schedule == null)
                return false;

            db.Schedules.Remove(schedule);
            db.SaveChanges();
            return true;
        }

        public Boolean RemoveSchedules(List<int> scheduleIds)
        {
            Boolean error = true;
            foreach (int id in scheduleIds)
            {
                error = RemoveSchedule(id);
                if (!error) return false;
            }
            db.SaveChanges();
            return true;
        }

        public Boolean DeleteWholeScheduledTour(int tourId)
        {
            Boolean error = true;
            IQueryable<Schedule> schedules = db.Schedules.Where(o => o.TourId == tourId);
            foreach (Schedule schedule in schedules)
            {
                error = RemoveSchedule(schedule.Id);
                if (!error) return false;
            }
            db.SaveChanges();
            return true;
        }
        #endregion

        #region Interface Methods - Get
        public IQueryable<Schedule> GetScheduleByTour(int tourId)
        {
            return db.Schedules.Where(o => o.TourId == tourId);
        }

        public Schedule GetScheduleById(int scheduleId)
        {
            return db.Schedules.Where(o => o.Id == scheduleId).FirstOrDefault();
        }
        #endregion
    }
}